package com.jflm.util;

import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * ******************  类说明  *********************
 * class       :  XmlUtils
 * @author     :  hejinyun@umpay.com
 * @version    :  1.0  
 * description :  xml报文解析工具类
 * @see        :                        
 * ***********************************************
 */
public class XmlUtils {

	private static final Logger LOG = LoggerFactory.getLogger(XmlUtils.class);
	private static DocumentBuilder builder = null;
	
	static {
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
		try {
			builder = builderFactory.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			LOG.error("#parse() 生成builderFactory异常", e);
		}
	}
	
	public static Map<String, String> fromXML(String xml, String parentNode) {
		Document document = XmlUtils.parse(xml);
		Element root = document.getDocumentElement();
		NodeList nodeList = root.getElementsByTagName(parentNode);
		LinkedHashMap<String, String> linkedHashMap = XmlUtils.parseChildNodes(nodeList);
		return linkedHashMap;
	}
	
	public static Document parse(String xml) {
		Document document = null;
		try {
			document = builder.parse(new InputSource(new StringReader(xml)));
		} catch (SAXException e) {
			LOG.error("#parse() 生成builderFactory异常", e);
		} catch (IOException e) {
			LOG.error("#parse() 生成builderFactory异常", e);
		}
		return document;
	}


	public static Map<String, String> fromXML(String xml) {
		/**
		 * 如果报文中带有CRLF：换行 空格符，这种报文没法解析
		 */
		xml = xml.replaceAll(">\\s+<", "><");
		Document document = XmlUtils.parse(xml);
		Element root = document.getDocumentElement();
		NodeList nodeList = root.getChildNodes();
		LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<String, String>();
		for (int index = 0; index < nodeList.getLength(); index++){
			Element child =  (Element) nodeList.item(index);
			String name = child.getNodeName();
			String value = child.getTextContent();
			linkedHashMap.put(name, value);
		}
		return linkedHashMap;
	}
	
	public static LinkedHashMap<String, String> parseChildNodes(NodeList nodeList){
		if (null == nodeList) {
			return null;
		}
		Element parent = (Element) nodeList.item(0);
		NodeList childNodeList = parent.getChildNodes();
		LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<String, String>();
		for (int index = 0; index < childNodeList.getLength(); index++){
			Element child =  (Element) childNodeList.item(index);
			String name = child.getNodeName();
			String value = child.getTextContent();
			linkedHashMap.put(name, value);
		}
		return linkedHashMap;
	}
	
	public static String getDataContent(String xml, String nodeName) {
		if (StringUtils.isBlank(xml)){
			return "";
		}
		String beginNodeName = "<"+nodeName+">";
		String endNodeName = "</"+nodeName+">";
		int skip = beginNodeName.length()+1;
		int beginIndex = xml.indexOf(beginNodeName);
		int endIndex = xml.indexOf(endNodeName)+skip;
		if (beginIndex >= endIndex){
			return "";
		}
		return xml.substring(beginIndex, endIndex);
	}
	
	public static void main(String[] args) {
		
		Map<String, LinkedHashMap<String, String>> paramsMap = new HashMap<String, LinkedHashMap<String, String>>();
//		String xml = "<?xml version='1.0' encoding='UTF-8' standalone='yes'?><data><accessToken>345353</accessToken><mobileNo>1234</mobileNo><merId>1234</merId><userId>43534534</userId><bizCode>0000</bizCode><bizDesc>成功</bizDesc></data>";
//		String xml = "<?xml version='1.0' encoding='UTF-8'?><bizdata><data><version>1.0.0</version><merId>商户号（联盟分配）</merId><mobileId>联盟手机号</mobileId><userId>用户id（中行token）</userId><reqNo>请求流水号（请求唯一标识）</reqNo><reqTime>请求时间（YYYYMMDDHHmmss）</reqTime></data><sign><idx>001</idx><value>签名值</value></sign></bizdata>";
		String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?> <data>\r\n<accessToken>DuPCBjr1tAjU6+BDtGcxHhee+mjqGOgQu69ia8gQA11jBH0qSHPRAv5p0+qL7gK9INbJ4vL32cMJ7bmBRosjnBvsYHaVC7Bnrlm3i6BCwHDqeevYxQHdu7JD/nfBH11KT/d2TpmK/sAxl6xFtidlyNIC4OmeVBZCCbs1iH6Y8m4=</accessToken><mobileNo>R7fwFwAA0QIhXHuCMN/SxUa728EOn5lILQ3f8oKYYH0uqoH8EEAX+uMzm4fMOrzXy+NNv5Dt3lQwPdrJXxTdIwSslIOJYa5isOVpOIEI/FZedbG5NRXo1cfeeal9blV2I/QZGP8gZDU5fS2EASLkUQP55Jwv3qmbIZvRMtXM4YU=</mobileNo><merId>hASFXeXLdOG5wJvjBlnqsBKQppmp9n0EwckKf2gkDVwlML0368RmLpJRG22iKUWvb9lWzuhe45bSv9M71g1R5h2QtwIYnbOgUfJQEBmPE+9cbPxMBeIrAIv3wMXCb/UhBviqB9SWMeW2Hw1D4KsFLcR2BoTdmsZIf16HvwCsfuo=</merId><userId>gVk/Z5SX0JjaBAYQvNzGf4MnAZbRpuk35EvDhGU4Omj5PdMFu50kYvK10HhlL2Yr6td0O9sXsuo3HkdLRWpnq8fUoOeFvEGfEtdDRn8RpL2l+q/cHaYuKzCGiiF60fvfL3nWMnRIfnd4AzgjBvMiST/CkZgFkz/AJTQUCaBLcF4=</userId><bizCode>0000</bizCode><bizDesc>   成功</bizDesc></data>";
//		XmlUtils parser = new XmlUtils();
//		Document document = parser.parse(xml);
//		Element root = document.getDocumentElement();
//		NodeList nodeList = root.getElementsByTagName("sign");
//		LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<String, String>();
//		linkedHashMap = XmlUtils.parseChildNodes(nodeList);
//		System.out.println(linkedHashMap);
		
//		LinkedHashMap<String, String> result = XmlUtils.parseChildNodes(nodeList);
//		System.out.println(result);
//		LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<String, String>();
//		linkedHashMap.put("accessToken", "20161212000000000");
//		linkedHashMap.put("orderCode", "20161212000000000");
//		paramsMap.put("data", linkedHashMap);
//		
//		StringBuffer xml = new StringBuffer("<?xml version='1.0' encoding='UTF-8' standalone='yes'?>");
//		for (Map.Entry<String, LinkedHashMap<String, String>> root:paramsMap.entrySet()){
//			String rootKey = root.getKey();
//			xml.append("<"+rootKey+">");
//			LinkedHashMap<String, String> childMap = root.getValue();
//			for (Map.Entry<String, String> child: childMap.entrySet()){
//				String childKey = child.getKey();
//				String childValue = child.getValue();
//				xml.append("<"+childKey+">");
//				xml.append(childValue);
//				xml.append("</"+childKey+">");
//			}
//			xml.append("</"+rootKey+">");
//		}
//		System.out.println(xml);
		
//		System.out.println(XmlUtils.getDataContent(xml, "data"));
		
//		String source = XmlUtils.getDataContent(xml, "data");
//		System.out.println(source);
//		XmlUtils.fromXML(xml, "data");
		System.out.println(xml);
		xml = xml.replaceAll("\r\n", "");
		System.out.println(xml);
		Map<String, String> data = XmlUtils.fromXML(xml);
		System.out.println(data);
	}
}
